﻿using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.IO;
using System.Xml.Linq;
using Red.Core;
using static System.Windows.Application;

namespace Red.Launcher.ViewModels
{
    public class RecentFiles : ViewModel
    {
        #region Private Data

        private bool _hasPaths;

        #endregion Private Data

        #region Public Properties

        public ObservableCollection<string> Paths { get; private set; } = new ObservableCollection<string>();

        public static string ToolkitDataDirectoryPath
        {
            get
            {
                string userProfilePath = Environment.GetFolderPath( Environment.SpecialFolder.ApplicationData );
                string groupPath = "CD Projekt Red";
                string appPath = "Red Toolkit";
                return System.IO.Path.Combine( userProfilePath, groupPath, appPath );
            }
        }

        public static string Filename => "RecentFiles.xml";

        public static string Path => System.IO.Path.Combine( ToolkitDataDirectoryPath, Filename );

        public bool HasPaths
        {
            get
            {
                return _hasPaths;
            }

            private set
            {
                if ( _hasPaths != value )
                {
                    _hasPaths = value;
                    OnPropertyChanged();
                }
            }
        }

        #endregion Public Properties

        #region C-Tor

        public RecentFiles()
        {
            Paths.CollectionChanged += Paths_CollectionChanged;

            Read();
            ActivateMonitor();
        }

        #endregion C-Tor

        #region Public Methods

        public void Read()
        {
            if ( File.Exists( Path ) )
            {
                XDocument doc = XDocument.Load( Path );
                XElement root = doc.Element( "recent" );

                foreach ( XElement file in root.Elements( "file" ) )
                {
                    Paths.Add( file.Value );
                }
            }
        }

        #endregion Public Methods

        #region Private Methods

        private void ActivateMonitor()
        {
            // Ensure the directory exists as the FileSystemWatcher will throw an exception if it doesn't
            DirectoryInfo info = new DirectoryInfo( ToolkitDataDirectoryPath );
            if ( !info.Exists )
            {
                info.Create();
            }

            FileSystemWatcher myWatcher = new FileSystemWatcher();
            myWatcher.Path = ToolkitDataDirectoryPath;
            myWatcher.Filter = Filename;
            myWatcher.IncludeSubdirectories = false;
            myWatcher.EnableRaisingEvents = true;
            myWatcher.Changed += MyWatcher_Changed;
        }

        #endregion Private Methods

        #region Event Handlers

        private void Paths_CollectionChanged( object sender, NotifyCollectionChangedEventArgs e )
        {
            if ( !HasPaths && Paths.Count > 0 )
            {
                HasPaths = true;
            }
            else if ( HasPaths && Paths.Count == 0 )
            {
                HasPaths = false;
            }
        }

        private void MyWatcher_Changed( object sender, FileSystemEventArgs e )
        {
            Current.Dispatcher.BeginInvoke
            (
                (Action)( () =>
                 {
                     Paths.Clear();
                     Read();
                 } )
            );
        }

        #endregion Event Handlers
    }
}
